# app-engine imports
from google.appengine.ext import db
from google.appengine.api import users


# State types to be acccessed from templates
TEMPLATE_STATE_TYPES = {}

class User(db.Model):
  # Google accounts user
  google_user = db.UserProperty()
  # nick name is unique in this app
  nickname = db.StringProperty(multiline=False)
  # User types
  is_sys_admin = db.BooleanProperty()
  is_request_mod = db.BooleanProperty()
  is_donor_mod = db.BooleanProperty()
  is_manufacturer_mod = db.BooleanProperty()
  # description
  description = db.StringProperty(multiline=True)

class UserLevelApplication(db.Model):
  creator = db.ReferenceProperty(User)
  # user type
  SYS_ADMIN = 1
  REQUEST_MOD = 2
  DONOR_MOD = 3
  MANUFACTURER_MOD = 4
  type = db.IntegerProperty()
  request_note = db.StringProperty()
  response_note = db.StringProperty()
  # state
  PENDING = 0
  APPROVED = 1
  DENIED = 2
  state = db.IntegerProperty()
  date = db.DateTimeProperty(auto_now_add=True)

# Accessable by templates
TEMPLATE_STATE_TYPES['UserLevelApplication_SYS_ADMIN'] = \
  UserLevelApplication.SYS_ADMIN
TEMPLATE_STATE_TYPES['UserLevelApplication_REQUEST_MOD'] = \
  UserLevelApplication.REQUEST_MOD
TEMPLATE_STATE_TYPES['UserLevelApplication_DONOR_MOD'] = \
  UserLevelApplication.DONOR_MOD
TEMPLATE_STATE_TYPES['UserLevelApplication_MANUFACTURER_MOD'] = \
  UserLevelApplication.MANUFACTURER_MOD
TEMPLATE_STATE_TYPES['UserLevelApplication_PENDING'] = \
  UserLevelApplication.PENDING
TEMPLATE_STATE_TYPES['UserLevelApplication_APPROVED'] = \
  UserLevelApplication.APPROVED
TEMPLATE_STATE_TYPES['UserLevelApplication_DENIED'] = \
  UserLevelApplication.DENIED

def GetUserLevelApplicationTypeStr(type):
  if type == UserLevelApplication.SYS_ADMIN:
    return "system admin"
  if type == UserLevelApplication.REQUEST_MOD:
    return "request moderator"
  if type == UserLevelApplication.DONOR_MOD:
    return "donor moderator"
  if type == UserLevelApplication.MANUFACTURER_MOD:
    return "manufacturer moderator"
  return "unknown"

def GetUserLevelApplicationStateStr(state):
  if state == UserLevelApplication.PENDING:
    return "pending"
  if state == UserLevelApplication.APPROVED:
    return "approved"
  if state == UserLevelApplication.DENIED:
    return "denied"
  return "unknown"

class DonorProfile(db.Model):
  creator = db.ReferenceProperty(User)
  name = db.StringProperty(multiline=False)
  description = db.StringProperty(multiline=True)
  email = db.StringProperty(multiline=False)
  phone = db.StringProperty(multiline=False)
  address = db.StringProperty(multiline=False)
  website = db.StringProperty(multiline=False)
  date = db.DateTimeProperty(auto_now_add=True)
  # State
  PENDING  = 0
  ACTIVE   = 1
  DELETED = 2
  state = db.IntegerProperty()

# Accessable by templates
TEMPLATE_STATE_TYPES['DonorProfile_PENDING'] =  DonorProfile.PENDING
TEMPLATE_STATE_TYPES['DonorProfile_ACTIVE'] =  DonorProfile.ACTIVE
TEMPLATE_STATE_TYPES['DonorProfile_DELETED'] =  DonorProfile.DELETED

class ManufacturerProfile(db.Model):
  creator = db.ReferenceProperty(User)
  name = db.StringProperty(multiline=False)
  description = db.StringProperty(multiline=True)
  email = db.StringProperty(multiline=False)
  phone = db.StringProperty(multiline=False)
  address = db.StringProperty(multiline=False)
  website = db.StringProperty(multiline=False)
  date = db.DateTimeProperty(auto_now_add=True)
  # State
  PENDING = 0
  ACTIVE  = 1
  DELETED = 2
  state = db.IntegerProperty()

# Accessable by templates
TEMPLATE_STATE_TYPES['ManufacturerProfile_PENDING'] =  ManufacturerProfile.PENDING
TEMPLATE_STATE_TYPES['ManufacturerProfile_ACTIVE'] =  ManufacturerProfile.ACTIVE
TEMPLATE_STATE_TYPES['ManufacturerProfile_DELETED'] =  ManufacturerProfile.DELETED

class Message(db.Model):
  creator = db.ReferenceProperty(User)
  message = db.StringProperty(multiline=True)
  date = db.DateTimeProperty(auto_now_add=True)
  key_str = db.StringProperty(multiline=False)

class Request(db.Model):
  creator = db.ReferenceProperty(User)
  # State
  PENDING = 0
  OPEN = 1
  FUNDED = 2
  SHIP = 3 # manufacturer submitted an order
  CLOSED = 4
  DELETED = 5
  state = db.IntegerProperty()
  item_name = db.StringProperty(multiline=False)
  item_description = db.StringProperty(multiline=True)
  estimated_price = db.IntegerProperty()
  source = db.StringProperty()
  creation_date = db.DateTimeProperty(auto_now_add=True)
  deadline_date = db.DateTimeProperty()
  location = db.StringProperty()
  contact_info = db.StringProperty()
  notifiers = db.StringListProperty() # list of str(user.Key)
  num_pledges = db.IntegerProperty()
  num_orders = db.IntegerProperty()
  # Messages are created with same key

# Accessable by templates
TEMPLATE_STATE_TYPES['Request_PENDING'] =  Request.PENDING
TEMPLATE_STATE_TYPES['Request_OPEN'] =  Request.OPEN
TEMPLATE_STATE_TYPES['Request_FUNDED'] =  Request.FUNDED
TEMPLATE_STATE_TYPES['Request_SHIP'] =  Request.SHIP
TEMPLATE_STATE_TYPES['Request_CLOSED'] =  Request.CLOSED
TEMPLATE_STATE_TYPES['Request_DELETED'] =  Request.DELETED

class Pledge(db.Model):
  donor_profile = db.ReferenceProperty(DonorProfile)
  request = db.ReferenceProperty(Request)
  amount = db.IntegerProperty()
  description = db.StringProperty(multiline=True)
  # State
  OPEN = 0
  CLOSED = 1
  state = db.IntegerProperty()

# Accessable by templates
TEMPLATE_STATE_TYPES['Pledge_OPEN'] =  Pledge.OPEN
TEMPLATE_STATE_TYPES['Pledge_CLOSED'] =  Pledge.CLOSED

# Can only be created by admin, maufacturer moderator and creator
class Order(db.Model):
  manufacturer_profile = db.ReferenceProperty(ManufacturerProfile)
  request = db.ReferenceProperty(Request)
  # State
  OPEN = 0
  PARTIAL_FUNDED = 1
  FUNDED = 2
  IN_PROGRESS = 3
  COMPLETED =4
  state = db.IntegerProperty()
  description = db.StringProperty(multiline=True)
  # Messages are created with same key

# Accessable by templates
TEMPLATE_STATE_TYPES['Order_OPEN'] = Order.OPEN
TEMPLATE_STATE_TYPES['Order_PARTIAL_FUNDED'] = Order.PARTIAL_FUNDED
TEMPLATE_STATE_TYPES['Order_FUNDED'] = Order.FUNDED
TEMPLATE_STATE_TYPES['Order_IN_PROGRESS'] = Order.IN_PROGRESS
TEMPLATE_STATE_TYPES['Order_COMPLETED'] = Order.COMPLETED
